package stocks.server;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.sql.ResultSet;
import java.util.*;

import stocks.server.*;
@SuppressWarnings("serial")

public class Server extends UnicastRemoteObject implements Runnable, StockServerInterface,CallBack {
	private JdbcConnect dbcon;
	private SQLQueries execQuery;
	private StockQueue stockQueue;
	private CallBack currentClient = null;
	private List<CallBack> clients = new LinkedList<CallBack>();
	
	public Server() throws RemoteException {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * Start server and fork off thread
	 */
	public void start() {
		Thread thread;
		thread = new Thread(this); 
		thread.start();
		try {
			thread.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/*
	 * OSX (250)
Ria (340)
NIBC (290)
Vienta (170)
BHT (260)
Cones (470)
	 */
		
	/**
	 * Get local name ( used for callbacks )
	 */
	public String getName() {
		return "Server";
	}
	
	public void transactionCompleteSold(String message) {
		// shit was sold bro! do something
	}
	
	/*
	 * (non-Javadoc)
	 * @see stocks.server.StockServerInterface#requestBuy(stocks.server.CallBack, java.lang.String, int, int)
	 */
	public int requestBuy(CallBack c, String tag, int price, int quantity) throws java.rmi.RemoteException {
		stockQueue.pushBuying(tag, price, c.getName(), quantity, c);
		stockQueue.doBuyStocks();
		return 1;
	}
	/*
	 * (non-Javadoc)
	 * @see stocks.server.StockServerInterface#requestSell(stocks.server.CallBack, java.lang.String, int, int)
	 */
	public void requestSell(CallBack c, String tag, int price, int quantity) throws java.rmi.RemoteException {
		stockQueue.pushSelling(tag, price, c.getName(), quantity, c);
		stockQueue.doBuyStocks();
	}
	/*
	 * (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		try {
			stockQueue = new StockQueue(this);
			Stock OSX = new Stock("OSX",250,10000,null);
			Stock Ria = new Stock("Ria",340,10000,null);
			Stock NIBC = new Stock("NIBC",290,10000,null);
			Stock Vienta = new Stock("Vienta",170,10000,null);
			Stock BHT = new Stock("BHT",260,10000,null);
			Stock Cones = new Stock("Cones",470,10000,null);
			
			stockQueue.addStock(OSX, this);
			stockQueue.addStock(Ria, this);
			stockQueue.addStock(NIBC, this);
			stockQueue.addStock(Vienta, this);
			stockQueue.addStock(BHT, this);
			stockQueue.addStock(Cones, this);
			
			Registry reg = java.rmi.registry.LocateRegistry.createRegistry(1099);
			//Naming.rebind("StocksServer", this);
			reg.rebind("StocksServer", this);
			execQuery = new SQLQueries();
			
		} catch (Exception e) {
			System.out.println("RMI Listening failed");
			System.exit(0);
		}
	}
	
	/*
	 *  Connect to database
	 */
	public void databaseConnect()
	{
		dbcon = new JdbcConnect();
		execQuery = dbcon.getQueries();
		dbcon.closeConnection();
	}
	
	/* 
	 * Get JDBC connection
	 */
	public JdbcConnect getDBConnection()
	{
		return dbcon;
	}

	/*
	 * (non-Javadoc)
	 * @see stocks.server.StockServerInterface#login(java.lang.String, java.lang.String)
	 */
	@Override
	public void login(String username, String password) throws RemoteException {
		// TODO Auto-generated method stub
		
		System.out.println("Login method on server invoked");
		System.out.println("Username: " + username + " Password: " + password + "\n");
		
		int retval = execQuery.userLogin(username, password);
		
		if(retval == 0)
		{
			currentClient.showMessage("Register failed");
		}
		else
		{
			currentClient.showMessage("Welcome " + username + ". UserID: " + retval);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see stocks.server.StockServerInterface#register(java.lang.String, java.lang.String)
	 */
	@Override
	public void register(String username, String password)
			throws RemoteException {
		// TODO Auto-generated method stub
		System.out.println("Register method on server invoked");
		System.out.println("Username: " + username + " Password: " + password + "\n");
		
		int retval = execQuery.userRegister(username, password);
		if(retval == 0)
		{
			currentClient.showMessage("Register failed");
		}
		else
		{
			currentClient.showMessage("Welcome " + username + ". UserID: " + retval);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see stocks.server.StockServerInterface#requestTransactions(stocks.server.CallBack, java.lang.String, java.lang.String)
	 */
	@Override
	public ArrayList<String> requestTransactions(CallBack c, String startDate, String endDate)
			throws RemoteException {
		
		System.out.println("Request transactions on server invoked");
		System.out.println("StartDate: " + startDate + " EndDate: " + endDate + "\n");
		
		return execQuery.getTransactions(startDate, endDate);
		
	}

	@Override
	public void transactionCompleteBuy(String message) throws RemoteException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void transactionFailed(String message) throws RemoteException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void loginSucsess(String message) throws RemoteException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void joinedMessage(String from) throws RemoteException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void registerClient(CallBack client)
			throws RemoteException {
		// TODO Auto-generated method stub
		System.out.println("Registering client");
		currentClient = client;
	}

	@Override
	public void showMessage(String msg) throws RemoteException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public ArrayList<String> getStockPrices(CallBack client)
			throws RemoteException {
		// TODO Auto-generated method stub
		return execQuery.getStockPrices();
	}
	
	//public void addCompletedOrder(String transactionID, int stockcode, String stockname, int userid, int qty, int price)
	public void addCompletedOrder(String transactionID,String stockName,String userName,int qty,int price)
	{
		execQuery.addCompletedOrder(transactionID, getStockID(stockName), stockName, getUserID(userName), qty, price);
	}
	public int getUserID(String username)
	{
		return execQuery.getUserID(username);
	}
	
	public int getStockID(String username)
	{
		return execQuery.getStockID(username);
	}
}
